package com.tomagency.cyberlab.client.activity;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.HasText;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;
import com.google.web.bindery.requestfactory.shared.Violation;
import com.tomagency.cyberlab.client.ClientFactory;
import com.tomagency.cyberlab.client.events.ObjectEvent;
import com.tomagency.cyberlab.client.events.WindowScrollEvent;
import com.tomagency.cyberlab.client.place.ObjectListenPlace;
import com.tomagency.cyberlab.client.ui.ObjectListenView;
import com.tomagency.cyberlab.client.ui.ObjectListenView.ObjectEventHandler;
import com.tomagency.cyberlab.client.ui.ObjectListenView.RenderType;

import de.gammadata.gwt.proxy.PersistenceBeanListProxy;

public abstract class AbstractListenActivity extends AbstractActivity {
	
	public static int LIMIT = 60;
	public static int SCROLL_WINDOW_PART=5;  // 1/x des fensters
	
	private ClientFactory clientFactory;
	private ObjectListenPlace place;
	private ObjectListenView view;
	private List currentBelegListe;
	
	private int start = 0;
	private int limit = LIMIT;
	
	private boolean dataFetchinProgress=false;
	private String uid;
	private String lastSuchText;
	private int currentRowNr;
	private int currentObjectId;


	private HasText messageWidget;
	
	public AbstractListenActivity(ObjectListenPlace place,ObjectListenView view,ClientFactory clientFactory){
		
		this.clientFactory=clientFactory;
		this.place=place;
		this.view=view;
		this.uid=this.getClass().getName()+System.currentTimeMillis();
		currentBelegListe = new ArrayList<Object>();
		
	}
	
	public abstract void setPresenterInView(ObjectListenView view);

	/* (non-Javadoc)
	 * @see com.google.gwt.activity.shared.Activity#start(com.google.gwt.user.client.ui.AcceptsOneWidget, com.google.gwt.event.shared.EventBus)
	 */
	@Override
	public void start(AcceptsOneWidget panel, EventBus eventBus) {
//		ObjectListenView view=clientFactory.getBelegListenView();
		
		panel.setWidget(view.asWidget());
		/*
		 * Prüfen ob der view schon mit diesem Presenter gelaufen ist
		 */
		if (view.getPresenter()!=null&&view.getPresenter().getUid().equalsIgnoreCase(this.uid)){
			//ja
		}
		else{ // nein neu aufbauen
//			view.setPresenter(this);
			setPresenterInView(view);
			view.render();
			onShowAllClicked();
		}
			
		

	}
	
	public void onListRequestCompleted(List response){
		currentBelegListe.addAll(response);
		view.setObjectList(currentBelegListe);
		view.renderObjectList(start, response.size(), start, RenderType.LIST);
		start +=response.size();						
		view.setMessage("Liste geholt Größe: "+currentBelegListe.size());
	}
	public abstract void holeListeVomServer();
	/*
	public void holeListeVomServer(){
		if (dataFetchinProgress)
			return;
//		searchTxt.setText("");
		view.setMessage("hole Daten vom Server ......");
//		errorLabel.setText("hole Daten vom Server");
		dataFetchinProgress=true;
		
		clientFactory.getRpcServiceProvider().getRequestFactory().belegRequest().findAllBelege(start,limit).fire(
				new Receiver<List>(){

					@Override
					public void onSuccess(List response) {	
						dataFetchinProgress=false;
						onListRequestCompleted(response);
						
					}


					@Override
					public void onFailure(ServerFailure error) {
						dataFetchinProgress=false;
						super.onFailure(error);
					}

					@Override
					public void onViolation(Set<Violation> errors) {
						dataFetchinProgress=false;
						super.onViolation(errors);
					}
					
				}
				);
	}
	*/

	
	public void onSearchRequestCompleted(List response){
		currentBelegListe=response;
		view.clearListenTabelle();
		view.setObjectList(currentBelegListe);
		start=0;
		view.renderObjectList(start, response.size(), start, RenderType.LIST);
		start +=response.size();						
		view.setMessage("Suchergebnis für: "+lastSuchText+", Anzahl gefundener Belege: "+response.size());
		
	}
	
	public abstract void sucheObjekte(String suchText);
	
	/*
	public void sucheBelege(String suchText){
		if (dataFetchinProgress)
			return;
		dataFetchinProgress=true;
		lastSuchText=suchText;
		view.setMessage("suche nach: "+suchText+", hole Daten vom Server");
		clientFactory.getRpcServiceProvider().getRequestFactory().belegRequest().findByMatchString(suchText).fire(
				new Receiver<List>(){

					@Override
					public void onSuccess(List response) {	
						
						onSearchRequestCompleted(response);
						dataFetchinProgress=false;
					}
					
					@Override
					public void onFailure(ServerFailure error) {
						dataFetchinProgress=false;
						super.onFailure(error);
					}

					@Override
					public void onViolation(Set<Violation> errors) {
						dataFetchinProgress=false;
						super.onViolation(errors);
					}
					
				}
				);
	}
	*/

	
	public void onObjectRequestCompleted(Object result, int rowNr){
		currentBelegListe.set(rowNr, result);
		setCurrentRowNr(rowNr);
		if (result instanceof PersistenceBeanListProxy){
			setCurrentObjectId(((PersistenceBeanListProxy)result).getId());
		}
		view.renderObjectList(rowNr, 1, rowNr, RenderType.FULL);
	}
	

	/**
	 * Muss für jedes EntityProxy spezifisch erstellt werden
	 * wird deshalb an die konkreten Implementierungen delegiert
	 * @param rowNr  Zeile in der Tabelle und Objektliste
	 * @param objectId Object-Id
	 */
	public abstract void onObjectClicked(int rowNr, int objectId);
/*
	public void onObjectClicked(int rowNr, int objectId) {
	
		clientFactory.getRpcServiceProvider().getRequestFactory().belegRequest().findBelegExt(objectId).with("adresse","kontakt","emailAdresse","versandArt","zahlungsBedingung","positionsListe","messageListe").fire(
					new Receiver<CyBelegProxy>(){

						@Override
						public void onSuccess(CyBelegProxy beleg) {
							onObjectRequestCompleted(beleg,currentRowNr);
//							renderListRow(beleg,selectedRow,RenderType.FULL);
//							Window.alert("Beleg geholt: "+beleg.getUuid()+ ", "+beleg.getSubject());

						}
						
					}
					);	
	}
	*/

	public void onCollapseObjectClicked(int objectId){
		setCurrentRowNrByObjectId(objectId);
		view.renderObjectList(getCurrentRowNr(), 1, getCurrentRowNr(), RenderType.LIST);
	}

	public void onObjectCollapseEvent(ObjectEvent event) {
		onCollapseObjectClicked(event.getObjectId());
		
	}


	
	public void onObjectEventStarted(ObjectEvent event){
		messageWidget=event.getMessageWidget();

		
	}
	public void onObjectEventCompleted(String message, boolean ok){
		if (messageWidget!=null&&message!=null){
			messageWidget.setText(message);
		}
		messageWidget=null; //um Referenz zu löschen 
		
		
	}


//	@Override
	public void onSearchClicked(String searchText) {
		sucheObjekte(searchText);
		
	}

//	@Override
	public void onShowAllClicked() {
		currentBelegListe = new ArrayList<Object>();
		view.clearListenTabelle();
		start = 0;
		limit = LIMIT;
		holeListeVomServer();		
	}
	
	/**
	 * Ask user before stopping this activity
	 */
//	@Override
//	public String mayStop() {
//		return "Please hold on. This activity is stopping.";
//	}

	/**
	 * Navigate to a new Place in the browser
	 */
	public void goTo(Place place) {
		clientFactory.getPlaceController().goTo(place);
	}

//	@Override
	public void onWindowScrollEvent(WindowScrollEvent event) {
		int scrollMargin = Window.getClientHeight()/SCROLL_WINDOW_PART;
		int appBottom = view.asWidget().getElement().getAbsoluteBottom();
		if (event.isScrollDown()&&(event.getTopPosition()+event.getClientHeight()>appBottom-scrollMargin)){
			
			
			if (!dataFetchinProgress){						
				holeListeVomServer();
			}
			else{
				view.setMessage("data fetch in progress");
			}
		}
		else{
//			view.setMessage("idle: down: "+event.isScrollDown()+ " top: "+event.getTopPosition()+ " bottom: "+appBottom);
		}
		
	}

//	@Override
	public String getUid() {
		return uid;
	}

//	@Override
	public void setUid(String uid) {
		this.uid=uid;
		
	}

	/**
	 * @return the clientFactory
	 */
	public ClientFactory getClientFactory() {
		return clientFactory;
	}

	/**
	 * @param clientFactory the clientFactory to set
	 */
	public void setClientFactory(ClientFactory clientFactory) {
		this.clientFactory = clientFactory;
	}

	/**
	 * @return the view
	 */
	public ObjectListenView getView() {
		return view;
	}

	/**
	 * @param view the view to set
	 */
	public void setView(ObjectListenView view) {
		this.view = view;
	}

	/**
	 * @return the currentBelegListe
	 */
	public List getCurrentBelegListe() {
		return currentBelegListe;
	}

	/**
	 * @param currentBelegListe the currentBelegListe to set
	 */
	public void setCurrentBelegListe(List currentBelegListe) {
		this.currentBelegListe = currentBelegListe;
	}

	/**
	 * @return the start
	 */
	public int getStart() {
		return start;
	}

	/**
	 * @param start the start to set
	 */
	public void setStart(int start) {
		this.start = start;
	}

	/**
	 * @return the limit
	 */
	public int getLimit() {
		return limit;
	}

	/**
	 * @param limit the limit to set
	 */
	public void setLimit(int limit) {
		this.limit = limit;
	}

	/**
	 * @return the dataFetchinProgress
	 */
	public boolean isDataFetchinProgress() {
		return dataFetchinProgress;
	}

	/**
	 * @param dataFetchinProgress the dataFetchinProgress to set
	 */
	public void setDataFetchinProgress(boolean dataFetchinProgress) {
		this.dataFetchinProgress = dataFetchinProgress;
	}

	/**
	 * @return the lastSuchText
	 */
	public String getLastSuchText() {
		return lastSuchText;
	}

	/**
	 * @param lastSuchText the lastSuchText to set
	 */
	public void setLastSuchText(String lastSuchText) {
		this.lastSuchText = lastSuchText;
	}

	/**
	 * @return the currentRowNr
	 */
	public int getCurrentRowNr() {
		return currentRowNr;
	}

	/**
	 * @param currentRowNr the currentRowNr to set
	 */
	public void setCurrentRowNr(int currentRowNr) {
		this.currentRowNr = currentRowNr;
	}
	
	public void setCurrentRowNrByObjectId(int id){
		int row=0;
		for (Object obj:getCurrentBelegListe()){
			if (obj instanceof PersistenceBeanListProxy&&((PersistenceBeanListProxy)obj).getId()==id){
				setCurrentRowNr(row);
				break;
			}
			row++;
		}
		
	}
	
	/**
	 * @return the currentObjectId
	 */
	public int getCurrentObjectId() {
		return currentObjectId;
	}

	/**
	 * @param currentObjectId the currentObjectId to set
	 */
	public void setCurrentObjectId(int currentObjectId) {
		this.currentObjectId = currentObjectId;
	}
	

//	@Override
//	public void onObjectEvent(H event) {
//		// TODO Auto-generated method stub
//		
//	}

}
